/**
 *
 */
package com.wfe.generics;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.hibernate.Session;

import com.wfe.db.EngineUtil;
import com.wfe.db.SessionUtil;
import com.wfe.db.WorkFlowEngineQueryUtil;
import com.wfe.mapping.client.WfContextAttribute;
import com.wfe.mapping.client.WfFirePlanAction;
import com.wfe.mapping.client.WfProject;
import com.wfe.mapping.client.WfProjectTask;
import com.wfe.mapping.client.WfProjectTaskStatus;

/**
 * @author kareem_yehya
 * @version 1.0.0.1 should be implemented when create any bussiness task
 */
public abstract class BussinessTask extends WfProjectTask implements Serializable
{

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * @author kareem_yehya
	 * @since 25 March 2009 This Method should be implemented for every business task The job engine consider it as entry point for task execution
	 * */

	/**
	 * @author kareem_yehya
	 * @since April 2009 <br>
	 *        Please call this method to initate Task fields before execution <br>
	 * 
	 * 
	 * */

	public void loadDummyTask(long taskID)
	{
		try
		{
			Session session = SessionUtil.getSession();
			List<WfProjectTask> tasklist = WorkFlowEngineQueryUtil.getWfProjectTask(session, taskID, 1);
			if(tasklist.size() > 0)
			{
				for(WfProjectTask task : tasklist)
				{
					this.setRecid(task.getRecid());
					this.setCreationTime(task.getCreationTime());
					this.setEndTime(task.getEndTime());
					System.out.println(task.getEndTime());
					this.setGroupId(task.getGroupId());
					this.setStartTime(task.getStartTime());
					this.setUserId(task.getUserId());
					this.setWfPlanTask(task.getWfPlanTask());
					this.setWfProject(task.getWfProject());
					this.setWfProjectTaskStatus(task.getWfProjectTaskStatus());
				}
			}
		}catch(Exception e)
		{
			System.out.println("Couldn't Load Expected Dummy Task");
			e.printStackTrace();
		}
	}

	public abstract void execute();

	/**
	 * Should be called when task done Success
	 * 
	 * 
	 * */
	public void taskSuccess()
	{
		// Session session = SessionUtil.getSession();
		WfProjectTask task = getWfProjectTaskById(this.getRecid());
		task.setWfProjectTaskStatus(getWfProjectTaskStatusByID(1));
		task.setEndTime(new Date());
		task.setUserId(0l);
		task.setGroupId(0l);
		updateTask(task);

	}

	public void taskProblem()
	{
		// Session session = SessionUtil.getSession();
		WfProjectTask task = getWfProjectTaskById(this.getRecid());
		task.setWfProjectTaskStatus(getWfProjectTaskStatusByID(7));
		task.setEndTime(new Date());
		task.setUserId(0l);
		task.setGroupId(0l);
		updateTask(task);
	}

	/**
	 * Should be called when task done Failed
	 * 
	 * 
	 * */
	public void taskFailed()
	{
		// Session session = SessionUtil.getSession();
		WfProjectTask task = getWfProjectTaskById(this.getRecid());
		task.setWfProjectTaskStatus(getWfProjectTaskStatusByID(2));
		task.setEndTime(new Date());
		task.setUserId(0l);
		task.setGroupId(0l);
		updateTask(task);
	}

	/**
	 * @author kareem_yehya
	 * @since 31 March 2009 <br>
	 *        Use this method to retrive any attribute value from context
	 * */

	public String getContextAttributeValue(String attributeName)
	{
		try
		{

			WfContextAttribute contextAttribute = getAttributeByName(attributeName);
			if(contextAttribute != null)
			{
				return contextAttribute.getAttributeValue();
			}
			else
			{

				return null;
			}

		}catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * @author kareem_yehya
	 * @since 31 March 2009 <br>
	 *        Use this method to retrive All the attributes related to this task
	 * */

	public List<WfContextAttribute> getWfContextAttributeList()
	{
		try
		{
			Session session = SessionUtil.getSession();
			List<WfContextAttribute> contextAttributes = WorkFlowEngineQueryUtil.getAllAttributesByWfProjectTask(this.getRecid(), session);
			EngineUtil.closeSession(session);
			return contextAttributes;

		}catch(Exception e)
		{

			e.printStackTrace();
			return null;
		}

	}

	/**
	 * @author kareem_yehya
	 * @since 31 March 2009 <br>
	 *        Use this method to retrive All the attributes related to this task
	 * */

	public List<WfContextAttribute> getWfContextAttributeList(int maxResults)
	{
		try
		{
			Session session = SessionUtil.getSession();
			List<WfContextAttribute> contextAttributes = WorkFlowEngineQueryUtil.getAllAttributesByWfProjectTask(this.getRecid(), session);
			EngineUtil.closeSession(session);
			return contextAttributes;

		}catch(Exception e)
		{

			e.printStackTrace();
			return null;
		}

	}

	/**
	 * @author kareem_yehya
	 * @since 01 April 2009 <br>
	 *        Please use this method to add any attribute to project context attribute
	 * 
	 * 
	 * */
	public boolean addContextAttribute(String attributeName, String attributeValue)
	{
		try
		{

			WfContextAttribute attribute = new WfContextAttribute();
			attribute.setAttributeName(attributeName);
			attribute.setAttributeValue(attributeValue);

			// ---------------------
			WfProject project = getWfProjectByID(this.getWfProject().getRecid());
			WfFirePlanAction wfFirePlanAction = project.getWfFirePlanAction();
			attribute.setWfFirePlanAction(wfFirePlanAction);
			attribute.setRecid(WorkFlowEngineQueryUtil.getRandomID());
			Session session = SessionUtil.getSession();
			WorkFlowEngineQueryUtil.addContextAttribute(attribute, session);
			EngineUtil.closeSession(session);
			System.out.println("Attribute has been Added Successfully  Attribute Name = " + attributeName + " Attribute Value = " + attributeValue);

			return true;

		}catch(Exception e)
		{
			System.out.println("Can't add new Attribute to the context Attributename = " + attributeName + "AttributeVlue = " + attributeValue);
			e.printStackTrace();
			return false;
		}

	}

	/**
	 * @author kareem_yehya
	 * @since 02 April 2009 <br>
	 *        Please use this method to update any attribute to project context attribute
	 * 
	 * 
	 * */
	public boolean updateContextAttribute(String attributeName, String attributeValue)
	{
		try
		{

			WfContextAttribute attribute = getAttributeByName(attributeName);
			if(attribute != null)
			{

				attribute.setAttributeValue(attributeValue);
				Session session = SessionUtil.getSession();
				WorkFlowEngineQueryUtil.updateContextAttribute(attribute, session);
				EngineUtil.closeSession(session);
				System.out.println("Attribute has been Updated Successfully  Attribute Name = " + attributeName + " Attribute Value = " + attributeValue);

			}
			else
			{
				addContextAttribute(attributeName, attributeValue);
			}

			return true;

		}catch(Exception e)
		{
			System.out.println("Can't update Attribute  Attribute Name = " + attributeName + " Attribute Value = " + attributeValue);
			e.printStackTrace();
			return false;
		}

	}

	public void updateTask(WfProjectTask task)
	{
		Session session = SessionUtil.getSession();
		WorkFlowEngineQueryUtil.updateWfProjectTask(task, session);
		EngineUtil.closeSession(session);

	}

	public WfProjectTaskStatus getWfProjectTaskStatusByID(long i)
	{
		Session session = SessionUtil.getSession();
		WfProjectTaskStatus projectTaskStatus = WorkFlowEngineQueryUtil.getWfProjectTaskStatusByID(i, session);
		EngineUtil.closeSession(session);
		return projectTaskStatus;
	}

	public WfProjectTask getWfProjectTaskById(Long recid)
	{
		Session session = SessionUtil.getSession();
		WfProjectTask projectTask = WorkFlowEngineQueryUtil.getWfProjectTask(session, recid, 10).get(0);
		EngineUtil.closeSession(session);
		return projectTask;
	}

	public void updateContextAttribute(WfContextAttribute attribute)
	{
		Session session = SessionUtil.getSession();
		WorkFlowEngineQueryUtil.updateContextAttribute(attribute, session);
		EngineUtil.closeSession(session);

	}

	public WfContextAttribute getAttributeByName(String attributeName)
	{
		final Session session = SessionUtil.getSession();
		WfContextAttribute contextAttribute = WorkFlowEngineQueryUtil.getContextAttributeByName(attributeName, this.getRecid(), session);
		EngineUtil.closeSession(session);
		return contextAttribute;

	}

	public WfProject getWfProjectByID(long projectID)
	{
		Session session = SessionUtil.getSession();
		WfProject project = WorkFlowEngineQueryUtil.getWfProjectByID(projectID, session);
		EngineUtil.closeSession(session);
		return project;

	}

}
